/*
 * File      : application.c
 * This file is part of RT-Thread RTOS
 * COPYRIGHT (C) 2009, RT-Thread Development Team
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rt-thread.org/license/LICENSE
 *
 * Change Logs:
 * Date           Author       Notes
 * 2009-01-05     Bernard      the first version
 * 2010-03-04     Magicoe      for LPC1766 version
 * 2010-05-02     Aozima       add led function
 * 2010-05-24     Bernard      add filesystem initialization and move led function to led.c
 * 2012-04-15     Bernard      enable components_init.
 */

#include <rtthread.h>
#include "platform.h"
#include "string.h"



#ifdef RT_USING_LWIP
#include <emac.h>
#include <netif/ethernetif.h>
extern int lwip_system_init(void);
#endif

#ifdef RT_USING_DFS
#include <dfs.h>
#include <dfs_posix.h>
#include <sd.h>
#include <dfs_init.h>
//#include <dfs_fs.h>
#include <dfs_elm.h>
#endif

#include <ctype.h>
#include "care.h"
#include "led.h"
#include "GPIB.h"
#include "rtc.h"
#include "IAP\IAP.h"
#include "timer_control.h"
#include "network\tcpserver.h"
//#include "network\tcpclient.h"



//ALIGN(RT_ALIGN_SIZE)

//static rt_uint8_t led_stack[ 256 ];
//static struct rt_thread led_thread;



extern rt_uint8_t strnicmp (const char * str1, const char * str2, rt_uint8_t n);
static char ln_buf[128],tmp_buf[128];

#define UART_CMD_SIZE      128
char uart0_line[UART_CMD_SIZE];
rt_uint8_t uart0_line_position;
char uart1_line[UART_CMD_SIZE];
rt_uint8_t uart1_line_position;
char uart2_line[UART_CMD_SIZE];
rt_uint8_t uart2_line_position;

//struct msg{
//    char data_ptr[128];    /* 数据块首地址 */
//    rt_uint8_t data_size;   /* 数据块大小   */
//};

///* 消息队列控制块 */
//static struct rt_messagequeue mq;
///* 消息队列中用到的放置消息的内存池 */
//static char msg_pool[1024];


//void send_op(void *data, rt_uint8_t length)
//{    
////	struct msg msg_ptr;
//	char buf[64];
//	
//	strncpy(buf+1, data, length);
////	msg_ptr.data_ptr = data;  /* 指向相应的数据块地址 */
//	buf[0] = length; /* 数据块的长度 */

//	/* 发送这个消息指针给 mq 消息队列 */
//	rt_mq_send(&mq, buf, sizeof(buf));
//}

//void message_handler()
//{    
////	struct msg msg_ptr; /* 用于放置消息的局部变量 */
//	char buf[64];

//	/* 从消息队列中接收消息到 msg_ptr 中 */
//	rt_memset(&buf[0], 0, sizeof(buf));
//	if (rt_mq_recv(&mq, buf, sizeof(buf),-1) == RT_EOK)/* 成功接收到消息，进行相应的数据处理 *///RT_WAITING_NO,RT_WAITING_FOREVER
//	{       
//		rt_device_write(rt_device_find("uart1"), 0, (void*)(buf+1), buf[0]);
//	}
//}

void offline_read_setting()
{   //文件系统测试代码
    int fd=0,str_pos=0;
    rt_uint8_t i=0,count=1,read_success=0;
    char buf_str[128];

    rt_memset(ln_buf,0,128);
    if (PIN0_IS_CLR(SD_INSERT))
    {
        fd = open("/SETTING.txt",DFS_O_RDONLY,0);
        if(fd >= 0)
        {
            while ((count != 0)&&(i<MAX_OFFLINE_CMD))
            {
                read_success = 0;
                rt_memset(ln_buf,0,128);
                count = readln(ln_buf);
                if ((count>0)&&(ln_buf[0]!=0x0D)&&(ln_buf[1]!=0x0A))
                {
                    str_pos = 0;
                    rt_memset(tmp_buf,0,128);
                    if (strcpy(tmp_buf,strstr(ln_buf,"command")))
                        str_pos = strchr(tmp_buf,',') - tmp_buf;
                    if (str_pos>9) {
                        strncpy(offline_str[i].cmd,tmp_buf+9,str_pos-10);
                        read_success+=1;
                    }

                    str_pos = 0;
                    rt_memset(tmp_buf,0,128);
                    if (strcpy(tmp_buf,strstr(ln_buf,"filename")))//COPY从filename开始到结束的字符
                    {
                        str_pos = strchr(tmp_buf,';') - tmp_buf;
                        if (str_pos>9) {
                            strncpy(offline_str[i].file_name,tmp_buf+9,str_pos-9);
                            read_success+=1;
                        }
                    }

                    str_pos = 0;
                    rt_memset(tmp_buf,0,128);
                    memset(buf_str, 0, 128);
                    if (strcpy(tmp_buf,strstr(ln_buf,"time")))
                        str_pos = strchr(tmp_buf,',') - tmp_buf;
                    if (str_pos>5)
                    {
                        strncpy(buf_str,tmp_buf+5,str_pos-5);
                        offline_str[i].period = (unsigned short)atof(buf_str);
                        read_success+=1;
                    }

                    str_pos = 0;
                    rt_memset(tmp_buf,0,128);
                    memset(buf_str, 0, 128);
                    if (strcpy(tmp_buf,strstr(ln_buf,"address")))
                        str_pos = strchr(tmp_buf,',') - tmp_buf;
                    if (str_pos>8)
                    {
                        strncpy(buf_str,tmp_buf+8,str_pos-8);
                        offline_str[i].address = (unsigned char)atof(buf_str)&0xFF;
                        read_success+=1;
                    }
                    if (read_success==4)i++;
                }
            }
            close(fd);
            fd =0;
        }
    }

}


static void offline_entry(void* parameter)
{
    while (1)//(!UART_Auto_Mode)
    {
        if (PIN0_IS_SET(SW1))//按键弹起
        {
            if ((!offline_start)&&PIN0_IS_CLR(SD_INSERT)&&(SW_COUNT < 1000)&&(SW_COUNT > 5))//如果插入了TF卡以及离线采集没有启动
            {
                offline_start=1;
                read_once=0;
                SW_COUNT = 0;
            }

            if((SW_COUNT < 1000)&&(SW_COUNT > 5)&&(offline_start))//停止离线采集
            {
                NVIC_SystemReset();
                offline_start=0;
                offline_return=0;
                SW_COUNT = 0;
            }

            if((SW_COUNT>= 2000)&&(!offline_start)&&(!UART_Auto_Mode)) //长按启动listen only模式
            {
                Listen_Only_Mode = ~Listen_Only_Mode;
                SW_COUNT = 0;
            }
            SW_COUNT = 0;
            if (offline_start) {
                offline_collect();   //启动离线采集
            }
            if (Listen_Only_Mode) gpib_read(1,1,0,0);																							//启动TALK ONLY模式
        }
        if ((PIN0_IS_CLR(SD_INSERT))&&(read_once==1)) {
            read_once=0;    //插入TF卡重启CARE
            NVIC_SystemReset();
        }
        if (PIN0_IS_SET(SD_INSERT)) {
            read_once=1;	   //拔卡停止采集，再次启动离线采集重新读取TF配置文件
            offline_start=0;
        }
    }
}


struct rt_semaphore uart0_rx_sem;


static rt_err_t uart0_rx_ind(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&uart0_rx_sem);
    return RT_EOK;
}

void uart0_thread_entry(void *parameter)
{
    rt_uint8_t ch;	
    rt_sem_init(&uart0_rx_sem, "uart0_rx", 0, 0);
    rt_device_set_rx_indicate(rt_device_find("uart0"), uart0_rx_ind);
    while (1)
    {
        while (rt_device_read(rt_device_find("uart0"), -1, &ch, 1) != 1) rt_sem_take(&uart0_rx_sem, RT_WAITING_FOREVER);
				
//        if (ch == 0x08) uart0_line_position = 0;
        uart0_line[uart0_line_position] = ch;//toupper(ch);

        if ((uart0_line[0]!=0x08) && ((ch == '\n')))//||(ch == ';')))
        {
            if (uart0_line_position != 0)
            {
							if(care_protocol_state())
                    care_protocol(0,uart0_line,uart0_line_position+1);//strlen(uart0_line));
            }

            memset(uart0_line, 0, sizeof(uart0_line));
            uart0_line_position = 0;
            continue;
        }
        else if((uart0_line[0]==0x08)&&(uart0_line_position>2))
        {
            if(uart0_line_position == uart0_line[2]+2)
            {
                if(care_protocol_state())
                    care_protocol(0,uart0_line,uart0_line_position+1);

                memset(uart0_line, 0, sizeof(uart0_line));
                uart0_line_position = 0;
                continue;
            }
        }
        ch = 0;
        uart0_line_position ++;
        if (uart0_line_position >= UART_CMD_SIZE)
        {
            /* clear command line */
            uart0_line_position = 0;
        }

    } /* end of device read */
}




struct rt_semaphore uart1_rx_sem;


static rt_err_t uart1_rx_ind(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&uart1_rx_sem);
    return RT_EOK;
}


void uart1_thread_entry(void *parameter)
{
    char ch;
		char temp_line[128];
    rt_sem_init(&uart1_rx_sem, "uart1_rx", 0, 0);
    rt_device_set_rx_indicate(rt_device_find("uart1"), uart1_rx_ind);
    while (1)
    {
				while (rt_device_read(rt_device_find("uart1"), -1, &ch, 1) != 1) rt_sem_take(&uart1_rx_sem, RT_WAITING_FOREVER);
        uart1_line[uart1_line_position] = ch;//toupper(ch);
        if ((uart1_line[0]!=0x08) && ((ch == '\n')))//||(ch == ';')))
        {     
					if((CARE_WIFI_MODE == 1)||(UART_Auto_Mode == 1))
					{
						switch(WIFI_TR1)
						{
						case 0x01://+++
//							return_care(uart1_line,uart1_line,strlen(uart1_line));
							break;
						case 0x02://MAC
							if(strnicmp(uart1_line,"+OK=",4)== 0)
							{
								strcpy(temp_line,"WIFI_MAC:");
								strcat(temp_line,(strstr(uart1_line, "+OK=")+4));
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							break;
						case 0x05://SOCKET
							if(strnicmp(uart1_line,"+OK=",4)== 0)
							{
								strcpy(temp_line,"WIFI_SOCKET:");
								strcat(temp_line,(strstr(uart1_line, "+OK=")+4));
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							break;
						case 0x06://IPCFG
							if(strnicmp(uart1_line,"+OK=",4)== 0)
							{
								strcpy(temp_line,"WIFI_IPCFG:");
								strcat(temp_line,(strstr(uart1_line, "+OK=")+4));
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							break;
						case 0x18:
							if(strnicmp(uart1_line,"+OK",3)== 0)
							{
								strcpy(temp_line,"WIFI_SET:OK");
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							else if(strnicmp(uart1_line,"+ERR",4)== 0)
							{
								strcpy(temp_line,"WIFI_SET:ERR");
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							break;
						default:
							if(strnicmp(uart1_line,"+ERR",4)==0)
							{
								sprintf(temp_line,"WIFI_SET:ERR %d",WIFI_TR1);
								return_care(temp_line,temp_line,strlen(temp_line));
							}
							else if (WIFI_TR1==0xFF) return_care(uart1_line,uart1_line,strlen(uart1_line));
							break;
						}
						memset(temp_line, 0, sizeof(temp_line));
						memset(uart1_line, 0, sizeof(uart1_line));
						uart1_line_position = 0;
						continue;
					}
            if (uart1_line_position != 0)
            {
                if(care_protocol_state())
                    care_protocol(1,uart1_line,uart1_line_position+1);
            }

            memset(uart1_line, 0, sizeof(uart1_line));
            uart1_line_position = 0;
            continue;
        }
        else if((uart1_line[0]==0x08)&&(uart1_line_position>2))
        {
            if(uart1_line_position == uart1_line[2]+2)
            {
                if(care_protocol_state())
                    care_protocol(1,uart1_line,uart1_line_position+1);

                memset(uart1_line, 0, sizeof(uart1_line));
                uart1_line_position = 0;
                continue;
            }
        }

        ch = 0;
        uart1_line_position ++;
        if (uart1_line_position >= UART_CMD_SIZE)
        {
            /* clear command line */
            uart1_line_position = 0;
        }
    } /* end of device read */
}



struct rt_semaphore uart2_rx_sem;


static rt_err_t uart2_rx_ind(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&uart2_rx_sem);
    return RT_EOK;
}


void uart2_thread_entry(void *parameter)
{
    rt_uint8_t ch,pos;
    char constr[8];
    float sensor;

    rt_sem_init(&uart2_rx_sem, "uart2_rx", 0, 0);
    rt_device_set_rx_indicate(rt_device_find("uart2"), uart2_rx_ind);
    while (1)
    {
        while (rt_device_read(rt_device_find("uart2"), -1, &ch, 1) != 1) rt_sem_take(&uart2_rx_sem, RT_WAITING_FOREVER);
        /* handle end of line, break */
        //if (ch == '\r' || ch == '\n')
        if (uart2_line_position != 2 && (ch == '\n'))
        {
            /*
            31 2D CA AA B6 C8 20 3A 20 32 33 2E 32 38 20 25 20 0D 0A 								1-湿度 : 23.28 %
            31 2D CE C2 B6 C8 20 3A 20 32 37 2E 39 30 20 A1 E6 20 0D 0A							1-温度 : 27.90 ℃
            32 2D CE C2 B6 C8 20 3A 20 32 38 2E 33 30 20 A1 E6 20 0D 0A							2-温度 : 28.30 ℃
            32 2D C6 F8 D1 B9 20 3A 20 31 30 34 2E 30 37 20 6B 50 61 20 0D 0A				2-气压 : 104.07 kPa
            33 2D CE C2 B6 C8 20 3A 20 32 35 2E 30 30 20 A1 E6 20 0D 0A							3-温度 : 25.00 ℃
            */
            //34 2D CE C2 B6 C8 20 3A 20 30 2E 31 33 20 A1 E6 20 0D 0A 								0.13
            //34 2D CE C2 B6 C8 20 3A 20 2D 30 2E 30 36 20 A1 E6 20 0D 0A 						-0.06
            memset(constr,0,8);
            if(strrchr(uart2_line,' ')!=NULL) pos = strrchr(uart2_line,' ') - uart2_line;
            if((pos>12)&&(pos<20))
            {
                strncpy(constr,uart2_line+9,pos-9);//前面9字节
                sensor = atof(constr);
            }

            constr[0] = 0x31;
            constr[1] = 0x2D;
            constr[2] = 0xCA;
            constr[3] = 0xAA;
            constr[4] = 0xB6;
            constr[5] = 0xC8;
            constr[6] = 0x00;
            constr[7] = 0x00;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[0] = sensor;
            constr[0] = 0x31;
            constr[2] = 0xCE;
            constr[3] = 0xC2;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[1] = sensor;
            constr[0] = 0x32;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[2] = sensor;
            constr[0] = 0x32;
            constr[2] = 0xC6;
            constr[3] = 0xF8;
            constr[4] = 0xD1;
            constr[5] = 0xB9;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[3] = sensor;
            constr[0] = 0x33;
            constr[2] = 0xCE;
            constr[3] = 0xC2;
            constr[4] = 0xB6;
            constr[5] = 0xC8;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[4] = sensor;
            constr[0] = 0x34;
            if(strstr(uart2_line,constr)!=NULL) SENSOR_DATA[5] = sensor;

            memset(uart2_line, 0, sizeof(uart2_line));
            uart2_line_position = 0;
            continue;
        }
        /* normal character */
        uart2_line[uart2_line_position] = ch;//toupper(ch);

        ch = 0;
        uart2_line_position ++;
        if (uart2_line_position >= UART_CMD_SIZE)
        {
            /* clear command line */
            uart2_line_position = 0;
        }
    } /* end of device read */
}




static void led_thread_entry(void* parameter)
{

    rt_hw_led_init();
    LPC_GPIO0->FIODIR &= ~BV(SW1);
    LPC_GPIO0->FIODIR &= ~BV(SD_INSERT);
    LPC_GPIO0->FIODIR &= ~BV(nSUSPEND);

    LPC_GPIO2->FIODIR |=  BV(WIFI_RESET);
    LPC_GPIO2->FIODIR &= ~BV(WIFI_LINK);		//4
    LPC_GPIO2->FIODIR |=  BV(WIFI_nCTS);
    LPC_GPIO2->FIODIR &= ~BV(WIFI_nRTS);		//2

    LPC_PINCON->PINMODE1 &= ~(0x03L<<(2*(SW1-16)));				  //P0.25输入上拉
    LPC_PINCON->PINMODE1 |= (0x03L<<(2*(nSUSPEND-16)));			//P0.26输入下拉

    LPC_PINCON->PINMODE4 |= (0x03L<<(2*WIFI_LINK));					//P2.4输入下拉
    LPC_PINCON->PINMODE4 |= (0x03L<<(2*WIFI_nRTS));					//P2.2输入下拉

    LPC_GPIO2->FIODIR |=  BV(GPIO_5);
    LPC_GPIO0->FIODIR |=  BV(GPIO_6);
    LPC_GPIO0->FIODIR |=  BV(GPIO_7);
    LPC_GPIO0->FIODIR |=  BV(GPIO_8);

    PIN2_SET(GPIO_5);
    PIN0_SET(GPIO_6);
    PIN0_SET(GPIO_7);
    PIN0_SET(GPIO_8);

    PIN2_CLR(WIFI_nCTS);

    PIN2_CLR(WIFI_RESET);
    rt_thread_delay( RT_TICK_PER_SECOND/2);
    PIN2_SET(WIFI_RESET);

    while (1)
    {
        rt_hw_led_on(1);
        if(!UART_Auto_Mode)
            rt_thread_delay( RT_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */
        else
            rt_thread_delay( RT_TICK_PER_SECOND/10 );

        if (offline_start==1)rt_hw_led_on(2);
        else if (PIN0_IS_SET(nSUSPEND)||UART_Auto_Mode) rt_hw_led_off(1);

        if(!UART_Auto_Mode)
            rt_thread_delay( RT_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */
        else
            rt_thread_delay( RT_TICK_PER_SECOND/10 );
    }
}

/* thread phase init */
void rt_init_thread_entry(void *parameter)
{
    rt_thread_t tid;
		rt_err_t result;
    /* initialize platform */
    u32IAP_ReadSerialNumber(&LPC1768_NO[0],&LPC1768_NO[1],&LPC1768_NO[2],&LPC1768_NO[3]);	//mac address
    ReadFlash();																																	//configuration parameter

    platform_init();

    rt_hw_rtc_init();	 	//初始化RTC  //device简化

#ifdef RT_USING_LWIP
    /* register Ethernet interface device */
    lpc17xx_emac_hw_init();

    /* initialize lwip stack */
    /* register ethernetif device */
    eth_system_device_init();

    /* initialize lwip system */
    lwip_system_init();
//		websrv();
    tid = rt_thread_create("tcpserv",
                           tcpserv, RT_NULL,
                           1024, 1, 5);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }
		
#endif

    /* Filesystem Initialization */
#ifdef RT_USING_DFS
    rt_hw_sdcard_init();

    /* initialize the device file system */
    dfs_init();

#ifdef RT_USING_DFS_ELMFAT
    /* initialize the elm chan FatFS file system*/
    elm_init();
#endif

    /* mount sd card fat partition 1 as root directory */
    dfs_mount("sd0", "/", "elm", 0, 0);
    if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
        rt_kprintf("File System initialized!\n");
    else
        rt_kprintf("File System init failed!\n");
#endif

    timer_control_init();
    care_GPIB_init();

    read_once=0;
    WIFI_TR1=0xFF;
    UART_Auto_Mode = 0;
    protocol_state = 0;
    SW_COUNT = 0;
		AT_MODE = 0;
		rt_memset(CARE_SSID,0,64);  //device简化
		rt_memset(CARE_KEY,0,64);
		rt_memset(CARE_DMM,0,64);
		CARE_WIFI_MODE = 0;//0：SERVER模式，1：CLIENT模式
		
		
//    /* 初始化消息队列 */

//    result = rt_mq_init(&mq, 
//												"mqt",
//                        &msg_pool[0],             /* 内存池指向 msg_pool */
//                        64,                      /* 每个消息的大小是 1 字节 */
//                        sizeof(msg_pool),        	/* 内存池的大小是 msg_pool 的大小 */
//                        RT_IPC_FLAG_FIFO);       	/* 如果有多个线程等待，按照先来先得到的方法分配消息 */
																	
#ifdef RT_USING_DFS
    offline_start=0;
    offline_read_setting();
    Listen_Only_Mode = 0;
#endif


}

int rt_application_init()
{
    rt_thread_t tid;
    rt_err_t result;

    tid = rt_thread_create("init", rt_init_thread_entry, RT_NULL, 1024, RT_THREAD_PRIORITY_MAX/3, 5);
    if (tid != RT_NULL) rt_thread_startup(tid);

    tid = rt_thread_create("led", led_thread_entry, RT_NULL, 256, 5, 5);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }

    tid = rt_thread_create("uart0_serv", uart0_thread_entry, RT_NULL, 768, 1, 5);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }

		
		////device简化
    tid = rt_thread_create("uart1_serv", uart1_thread_entry, RT_NULL, 768, 1, 5);       
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }

    tid = rt_thread_create("uart2_serv", uart2_thread_entry, RT_NULL, 768, 1, 5);
    if (tid != RT_NULL)
    {
        rt_thread_startup(tid);
    }

    tid = rt_thread_create("offline", offline_entry, RT_NULL, 1024, 20, 20);
    if (tid != RT_NULL) rt_thread_startup(tid);
		
    return 0;
}
